import { Inject, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Instrument } from './entity/instrument.entity';
import { ListQueryDto } from './dto/list-query.dto';
import { RequestService } from 'src/request/request.service';
import { CreateInstrumentDto } from './dto/createInstrument.dto';
import { UpdateInstrumentDto } from './dto/updateInstrument.dto';
import { InstrumentMaintenanceDTO } from './dto/instrumentMaintenanc.dto';
import { InstrumentMaintenance } from './entity/instrument-maintenance.entity';

@Injectable()
export class InstrumentService {
  @InjectRepository(Instrument)
  private readonly instrumentRepository: Repository<Instrument>;
  @Inject()
  private readonly requestService: RequestService;
  @InjectRepository(InstrumentMaintenance)
  private readonly instrumentMaintenanceRepository: Repository<InstrumentMaintenance>;

  // 获取仪器信息
  async getInstrumentInfo(id: number) {
    return await this.instrumentRepository.findOne({
      where: { id },
      relations: ['category'],
    });
  }

  // 获取仪器列表
  async getList(query: ListQueryDto) {
    const { page = 1, limit = 30, id, categoryId, name, managerName } = query;
    const qb = this.instrumentRepository
      .createQueryBuilder('instrument')
      .leftJoinAndSelect('instrument.category', 'category');

    // id 支持多个值
    if (id) {
      const idList = String(id)
        .split(',')
        .map((i) => Number(i.trim()))
        .filter(Boolean);
      qb.andWhere('id IN (:...idList)', { idList });
    }

    // name 支持多个值
    if (name) {
      const nameList = String(name)
        .split(',')
        .map((n) => n.trim())
        .filter(Boolean);
      // 模糊查询
      if (nameList.length) {
        const conditions = nameList.map(
          (_, index) => `name LIKE :name${index}`,
        );
        const params = Object.fromEntries(
          nameList.map((n, i) => [`name${i}`, `%${n}%`]),
        );
        qb.andWhere(`(${conditions.join(' OR ')})`, params);
      }
    }

    // managerName 支持多个值
    if (managerName) {
      const {
        data: { list },
      } = await this.requestService.getManagerIds(managerName);
      const managerIds = list.map((item) => item.id);
      // 模糊查询
      if (managerIds.length) {
        const conditions = managerIds.map(
          (_, index) => `manager_id LIKE :manager${index}`,
        );
        const params = Object.fromEntries(
          managerIds.map((n, i) => [`manager${i}`, `%${n}%`]),
        );
        qb.andWhere(`(${conditions.join(' OR ')})`, params);
      }
    }

    if (categoryId) {
      qb.andWhere('category_id = :categoryId', { categoryId });
    }

    // 分页
    qb.skip((+page - 1) * +limit).take(+limit);

    const [list, total] = await qb.getManyAndCount();
    return {
      total,
      list: list.map((it) => {
        const { category, ...rest } = it;
        return {
          ...rest,
          categoryName: category?.name,
        };
      }),
    };
  }

  // 修改仪器管理员
  async saveManager(id: number, managerId: number) {
    return await this.instrumentRepository.update(id, {
      manager_id: managerId,
    });
  }

  // 新增仪器
  async createInstrument(createInstrumentDto: CreateInstrumentDto) {
    const { categoryId, ...field } = createInstrumentDto;
    const data = {
      category: { id: categoryId },
      ...field,
    };
    const instrument = await this.instrumentRepository.save(data);
    return instrument.id;
  }

  // 修改仪器信息
  async updateInstrument(id: number, updateInstrumentDto: UpdateInstrumentDto) {
    const { categoryId, ...field } = updateInstrumentDto;
    const data = {
      category: { id: categoryId },
      ...field,
    };
    return await this.instrumentRepository.update(id, data);
  }

  // 删除仪器
  async deleteInstrument(id: number) {
    return await this.instrumentRepository.delete(id);
  }

  // 仪器维修
  async maintenanceInstrument(data: InstrumentMaintenanceDTO) {
    // 转化loggerId
    const { loggerId, instrumentId, ...field } = data;
    console.log(data);
    return await this.instrumentMaintenanceRepository.save({
      logger_id: loggerId,
      instrument: { id: instrumentId },
      ...field,
    });
  }
}
